<template>
    <div class="file-upload-component">
        <label class="form-label" v-if="label">{{ label }}</label>
        <div 
            class="upload-area" 
            :class="{ 'disabled': disabled, 'error': error, 'loading': loading }"
            @click="triggerFileInput"
        >
            <input 
                type="file" 
                @change="handleFileChange" 
                :multiple="multiple"
                :accept="accept"
                class="file-input"
                ref="fileInput"
                style="display: none"
                :disabled="disabled || loading"
            >
            <div v-if="loading" class="loading-overlay">
                <van-loading type="spinner" color="#1E9FFF" />
                <span>上传中...</span>
            </div>
            <div v-else-if="!hasFiles" class="upload-placeholder">
                <van-icon name="description" size="24" />
                <span>{{ placeholder }}</span>
            </div>
            <div v-else class="files-preview">
                <div v-for="(file, index) in modelValue" :key="index" class="file-item">
                    <div class="file-info">
                        <van-icon name="description" size="16" />
                        <span class="file-name">{{ file.fileName }}</span>
                    </div>
                    <button @click.stop="removeFile(index)" class="remove-file-btn">
                        <van-icon name="cross" />
                    </button>
                </div>
                <div v-if="canAddMore" class="add-more">
                    <van-icon name="plus" size="24" />
                    <span>继续添加</span>
                </div>
            </div>
        </div>
        <div v-if="error" class="error-message">{{ errorMessage }}</div>
    </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { Icon as VanIcon, Loading as VanLoading, showToast } from 'vant';
import apiUrls from '@/config/apiUrls'; 
import request from '@/utils/request';

const props = defineProps({
    modelValue: {
        type: Array,
        default: () => []
    },
    label: {
        type: String,
        default: '上传文件'
    },
    placeholder: {
        type: String,
        default: '点击上传文件'
    },
    multiple: {
        type: Boolean,
        default: false
    },
    maxCount: {
        type: Number,
        default: 9
    },
    maxSize: {
        type: Number,
        default: 10 * 1024 * 1024 // 默认10MB
    },
    disabled: {
        type: Boolean,
        default: false
    },
    uploadType: {
        type: String,
        default: ''
    },
    accept: {
        type: String,
        default: '' // 默认不限制文件类型
    }
});

const emit = defineEmits(['update:modelValue', 'error']);

const fileInput = ref(null);
const error = ref(false);
const errorMessage = ref('');
const loading = ref(false);

const hasFiles = computed(() => {
    return props.modelValue.length > 0;
});

const canAddMore = computed(() => {
    return props.multiple && props.modelValue.length < props.maxCount;
});

const triggerFileInput = () => {
    if (props.disabled || loading.value) return;
    
    // 如果是单个文件模式且已经有文件，则不打开上传窗口
    if (!props.multiple && props.modelValue.length > 0) {
        showToast('只能上传一个文件');
        return;
    }
    
    if (fileInput.value) {
        fileInput.value.click();
    }
};

const handleFileChange = async (event) => {
    const files = event.target.files;
    if (!files.length) return;

    error.value = false;
    errorMessage.value = '';

    // 验证文件类型
    if (props.accept) {
        const acceptedTypes = props.accept.split(',').map(type => type.trim());
        for (const file of files) {
            const fileType = file.type.toLowerCase();
            const isValidType = acceptedTypes.some(type => {
                if (type.startsWith('.')) {
                    // 处理文件扩展名
                    return file.name.toLowerCase().endsWith(type.toLowerCase());
                } else {
                    // 处理MIME类型
                    return fileType === type.toLowerCase();
                }
            });
            
            if (!isValidType) {
                error.value = true;
                errorMessage.value = `只允许上传以下类型的文件: ${props.accept}`;
                event.target.value = '';
                return;
            }
        }
    }

    // 验证所有文件
    for (const file of files) {
        if (file.size > props.maxSize) {
            error.value = true;
            errorMessage.value = `文件大小不能超过 ${props.maxSize / 1024 / 1024}MB`;
            event.target.value = '';
            return;
        }
    }

    // 检查是否超过最大数量限制
    if (props.multiple) {
        if (props.modelValue.length + files.length > props.maxCount) {
            error.value = true;
            errorMessage.value = `最多只能上传 ${props.maxCount} 个文件`;
            event.target.value = '';
            return;
        }
    } else {
        // 单个上传时，只取第一个
        if (files.length > 1) {
            error.value = true;
            errorMessage.value = '只能上传一个文件';
            event.target.value = '';
            return;
        }
    }

    const formData = new FormData();
    Array.from(files).forEach((file) => {
        formData.append('files[]', file);
    });

    try {
        loading.value = true;
        const headers = {
            'Content-Type': 'multipart/form-data'
        };
        
        if (props.uploadType) {
            headers['zhjy-type'] = props.uploadType;
        }

        console.log('上传文件信息：', {
            files: Array.from(files).map(f => ({
                name: f.name,
                size: f.size,
                type: f.type
            })),
            headers
        });

        const response = await request.post(apiUrls.zhjy.getZhjyUploadFileUrl, formData, {
            headers
        });

        console.log('上传响应：', response);
        showToast(response.message);
        if (response.data) {
            // 处理上传响应
            const uploadedFiles = Array.isArray(response.data) ? response.data : [response.data];
            
            // 更新文件列表
            if (props.multiple) {
                const newFiles = [...props.modelValue, ...uploadedFiles];
                emit('update:modelValue', newFiles);
            } else {
                emit('update:modelValue', [uploadedFiles[0]]);
            }
        }
    } catch (error) {
        console.error('文件上传失败:', error);
        error.value = true;
        errorMessage.value = '文件上传失败，请重试';
        emit('error', error);
    } finally {
        loading.value = false;
        event.target.value = '';
    }
};

const removeFile = (index) => {
    const newFiles = [...props.modelValue];
    newFiles.splice(index, 1);
    emit('update:modelValue', newFiles);
};
</script>

<style scoped>
.file-upload-component {
    width: 100%;
    position: relative;
    z-index: 1;
}

.form-label {
    display: block;
    margin-bottom: 8px;
    color: #333;
    font-size: 14px;
}

.upload-area {
    border: 2px dashed #ddd;
    border-radius: 6px;
    padding: 12px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s;
    position: relative;
    background: white;
    min-height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.upload-area.loading {
    cursor: wait;
    border-color: #1E9FFF;
}

.upload-area.loading:hover {
    border-color: #1E9FFF;
}

.upload-area.disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

.upload-area.error {
    border-color: #ff4d4f;
}

.upload-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    color: #999;
    padding: 8px;
}

.upload-placeholder span {
    font-size: 14px;
}

.loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.9);
    gap: 8px;
    z-index: 1;
}

.loading-overlay span {
    color: #666;
    font-size: 14px;
}

.files-preview {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    position: relative;
    z-index: 0;
}

.file-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px;
    background: #f8f9fa;
    border-radius: 4px;
    border: 1px solid #eee;
}

.file-info {
    display: flex;
    align-items: center;
    gap: 8px;
}

.file-name {
    font-size: 14px;
    color: #333;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.remove-file-btn {
    background: none;
    border: none;
    color: #ff4d4f;
    cursor: pointer;
    padding: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.remove-file-btn:hover {
    color: #ff7875;
}

.add-more {
    aspect-ratio: 1;
    border: 2px dashed #ddd;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    color: #999;
    cursor: pointer;
    transition: all 0.3s;
    padding: 4px;
}

.add-more:hover {
    border-color: #1E9FFF;
    color: #1E9FFF;
}

.add-more .van-icon {
    font-size: 20px;
}

.add-more span {
    font-size: 12px;
}

.error-message {
    color: #ff4d4f;
    font-size: 12px;
    margin-top: 4px;
}
</style> 